package org.finesys.common.security.core.jackson;

import java.io.IOException;
import java.util.Set;

import org.finesys.common.security.core.module.AuthUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.MissingNode;

/**
 * 用户信息反序列化
 */
public class AuthUserJsonDeserializer extends JsonDeserializer<AuthUser> {
    private static final TypeReference<Set<SimpleGrantedAuthority>> SIMPLE_GRANTED_AUTHORITY_SET = new TypeReference<Set<SimpleGrantedAuthority>>() {
    };

    AuthUserJsonDeserializer() {
    }

    public AuthUser deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        JsonNode jsonNode = (JsonNode) mapper.readTree(jp);
        Set<? extends GrantedAuthority> authorities = (Set) mapper.convertValue(jsonNode.get("authorities"), SIMPLE_GRANTED_AUTHORITY_SET);
        JsonNode passwordNode = this.readJsonNode(jsonNode, "password");
        String username = this.readJsonNode(jsonNode, "username").asText();
        String password = passwordNode.asText("");
        boolean enabled = this.readJsonNode(jsonNode, "enabled").asBoolean();
        boolean accountNonExpired = this.readJsonNode(jsonNode, "accountNonExpired").asBoolean();
        boolean credentialsNonExpired = this.readJsonNode(jsonNode, "credentialsNonExpired").asBoolean();
        boolean accountNonLocked = this.readJsonNode(jsonNode, "accountNonLocked").asBoolean();
        AuthUser authUser = new AuthUser(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        if (passwordNode.asText((String) null) == null) {
            authUser.eraseCredentials();
        }
        //特殊字段赋值
        Long userId = this.readJsonNode(jsonNode, "userId").asLong();
        Long deptId = this.readJsonNode(jsonNode, "deptId").asLong();
        Long tenantId = this.readJsonNode(jsonNode, "tenantId").asLong();
        String email = this.readJsonNode(jsonNode, "email").asText();
        String phone = this.readJsonNode(jsonNode, "phone").asText();
        String sex = this.readJsonNode(jsonNode, "sex").asText();
        String appId = this.readJsonNode(jsonNode, "appId").asText();
        authUser.setUserId(userId).setDeptId(deptId).setTenantId(tenantId).setEmail(email).setPhone(phone).setSex(sex).setAppId(appId);
        return authUser;
    }

    private JsonNode readJsonNode(JsonNode jsonNode, String field) {
        return (JsonNode) (jsonNode.has(field) ? jsonNode.get(field) : MissingNode.getInstance());
    }
}
